package com.homework.papertexting.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.homework.papertexting.model.Paper;
import com.homework.papertexting.model.User;
import com.homework.papertexting.repository.PaperRepository;
import com.homework.papertexting.repository.UserRepository; // Corrected import
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/api/paper")
public class PaperController {

    private static final Logger logger = LoggerFactory.getLogger(PaperController.class);

    @Value("${dify.api.url}")
    private String difyApiUrl;

    @Value("${dify.api.key}")
    private String difyApiKey;

    @Value("${dify.workflow.id}")
    private String difyWorkflowId;

    @Value("${dify.workflow.file-variable-name}")
    private String difyWorkflowFileVariableName;

    @Value("${application.upload.dir}") // Corrected placeholder
    private String uploadDir;


    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    private final PaperRepository paperRepository;
    private final UserRepository userRepository; // Inject UserRepository


    public PaperController(RestTemplate restTemplate, ObjectMapper objectMapper, PaperRepository paperRepository, UserRepository userRepository/*, Environment env*/) {
        this.restTemplate = restTemplate;
        this.objectMapper = objectMapper;
        this.paperRepository = paperRepository;
        this.userRepository = userRepository;
    }


    @PostMapping("/upload")
    public ResponseEntity<?> uploadPaper(@RequestParam("file") MultipartFile file) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        logger.info("Authentication object is not null: {}", authentication != null);
        if (authentication == null || !authentication.isAuthenticated()) {
            logger.warn("User not authenticated.");
            // 使用 new ResponseEntity<>(body, status)
            return new ResponseEntity<>("用户未认证，无法上传文件。请先登录。", HttpStatus.UNAUTHORIZED);
        }

        Object principal = authentication.getPrincipal();
        User currentUser = null;
        if (principal instanceof User) {
            currentUser = (User) principal;
            logger.info("Successfully loaded custom User object for username: {}", currentUser.getUsername());
            logger.info("Authentication principal: {}", currentUser);
            logger.info("Authentication principal type: {}", principal.getClass().getName());
            logger.info("Authentication isAuthenticated(): {}", authentication.isAuthenticated());
        } else if (principal instanceof org.springframework.security.core.userdetails.User) {
            org.springframework.security.core.userdetails.User springUser = (org.springframework.security.core.userdetails.User) principal;
            Optional<User> userOptional = userRepository.findByUsername(springUser.getUsername()); // Use userRepository
            if(userOptional.isPresent()){
                currentUser = userOptional.get();
                logger.info("Successfully loaded custom User object for username: {}", currentUser.getUsername());
                logger.info("Authentication principal: {}", currentUser);
                logger.info("Authentication principal type: {}", principal.getClass().getName());
                logger.info("Authentication isAuthenticated(): {}", authentication.isAuthenticated());
            } else {
                logger.warn("User details found in SecurityContextHolder is Spring Security's User, but cannot find corresponding custom User in repository.");
                // 使用 new ResponseEntity<>(body, status)
                return new ResponseEntity<>("无法获取当前用户信息，请联系管理员。", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } else {
            logger.warn("Unknown principal type in SecurityContextHolder: {}", principal.getClass().getName());
            // 使用 new ResponseEntity<>(body, status)
            return new ResponseEntity<>("无法获取当前用户信息，请联系管理员。", HttpStatus.INTERNAL_SERVER_ERROR);
        }


        if (file.isEmpty()) {
            // 使用 new ResponseEntity<>(body, status)
            return new ResponseEntity<>("请选择一个文件进行上传。", HttpStatus.BAD_REQUEST);
        }

        // 声明 Paper 对象在 try 块外部
        Paper paper = null;

        try {
            // Get the current project root directory
            Path currentWorkingDir = Paths.get(".").toAbsolutePath();
            // Build the absolute path for the upload directory
            Path uploadPath = currentWorkingDir.resolve(uploadDir);

            logger.info("上传目录: {}", uploadPath.toString());

            // Create the directory if it doesn't exist
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
                logger.info("创建上传目录: {}", uploadPath.toAbsolutePath());
            } else {
                logger.info("上传目录已存在: {}", uploadPath.toAbsolutePath());
            }

            // Dify 文件上传不再需要本地文件，直接使用 MultipartFile 的字节流
            // Remove local file saving logic if not needed for other purposes


            // Call Dify file upload API to get file_id
            String uploadUrl = difyApiUrl + "/files/upload";
            logger.info("Calling Dify upload API: {}", uploadUrl);

            HttpHeaders uploadHeaders = new HttpHeaders();
            uploadHeaders.setBearerAuth(difyApiKey);
            uploadHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

            MultiValueMap<String, Object> uploadBody = new LinkedMultiValueMap<>();
            // Use ByteArrayResource to send file content from MultipartFile
            uploadBody.add("file", new ByteArrayResource(file.getBytes()) {
                @Override
                public String getFilename() {
                    return file.getOriginalFilename(); // Provide original file name to Dify
                }
            });
            uploadBody.add("user", currentUser.getId().toString()); // Use user ID

            ResponseEntity<String> uploadResponse = restTemplate.exchange(
                    uploadUrl,
                    HttpMethod.POST,
                    new HttpEntity<>(uploadBody, uploadHeaders),
                    String.class
            );

            logger.info("Received upload response from Dify. Status code: {}", uploadResponse.getStatusCode());
            logger.info("Upload response body: {}", uploadResponse.getBody());

            String difyFileId = null;
            if (uploadResponse.getStatusCode() == HttpStatus.CREATED) {
                JsonNode uploadResponseJson = objectMapper.readTree(uploadResponse.getBody());
                if (uploadResponseJson.has("id")) {
                    difyFileId = uploadResponseJson.get("id").asText();
                    logger.info("Uploaded file ID from Dify: {}", difyFileId);
                } else {
                    logger.error("Dify file upload response does not contain 'id'. Response: {}", uploadResponse.getBody());
                    // Save file info to database with status Dify upload failed
                    paper = new Paper(); // Initialize paper object
                    paper.setFileName(file.getOriginalFilename());
                    paper.setFileSize(file.getSize());
                    paper.setUploadTime(LocalDateTime.now());
                    paper.setUser(currentUser);
                    paper.setStatus("Dify 文件上传失败");
                    paper.setAiRawOutput("Dify 文件上传 API 返回格式异常，缺少文件 ID。");
                    paperRepository.save(paper);
                    logger.warn("File info saved to database with status 'Dify 文件上传失败' due to missing ID.");
                    return new ResponseEntity<>("Dify 文件上传失败，未返回文件 ID。", HttpStatus.INTERNAL_SERVER_ERROR);
                }
            } else {
                logger.error("Dify upload API returned non-CREATED status: {}", uploadResponse.getStatusCode());
                // Save file info to database with status Dify upload failed
                paper = new Paper(); // Initialize paper object
                paper.setFileName(file.getOriginalFilename());
                paper.setFileSize(file.getSize());
                paper.setUploadTime(LocalDateTime.now());
                paper.setUser(currentUser);
                paper.setStatus("Dify 文件上传失败");
                paper.setAiRawOutput("Dify 文件上传 API 返回错误: " + uploadResponse.getStatusCode() + " - " + uploadResponse.getBody());
                paperRepository.save(paper);
                logger.warn("File info saved to database with status 'Dify 文件上传失败'.");
                // 使用 new ResponseEntity<>(body, status)
                return new ResponseEntity<>("Dify 文件上传失败: " + uploadResponse.getBody(), uploadResponse.getStatusCode());
            }


            // Save file info to database (before calling workflow, to have paper ID)
            // If paper object was initialized in error handling above, re-initialize here for success path
            if(paper == null) {
                paper = new Paper();
                paper.setFileName(file.getOriginalFilename());
                paper.setFileSize(file.getSize());
                paper.setUploadTime(LocalDateTime.now());
                paper.setUser(currentUser);
                paper.setDifyFileId(difyFileId); // Save Dify file ID
                paper.setStatus("待检测"); // Set initial status to "Pending Detection"
                paper = paperRepository.save(paper);
                logger.info("File info saved to database with ID {} and Dify file ID: {}", paper.getId(), difyFileId);
            } else {
                // This case means paper was initialized in error handling, but somehow we reached here.
                // This shouldn't happen with current logic flow, but logging defensively.
                logger.warn("Paper object was already initialized before success path for saving to database.");
                // Attempt to update the existing paper object if it was saved with an error status
                if(paper.getId() != null) {
                    Optional<Paper> existingPaperOpt = paperRepository.findById(paper.getId());
                    if(existingPaperOpt.isPresent()){
                        paper = existingPaperOpt.get(); // Load the managed entity
                        paper.setDifyFileId(difyFileId); // Update Dify file ID
                        paper.setStatus("待检测"); // Update status
                        // Keep existing aiRawOutput or set to null depending on logic
                        paperRepository.save(paper);
                        logger.info("Updated existing Paper record with ID {} after Dify upload success.", paper.getId());
                    } else {
                        // This indicates a serious logic flaw, paper was initialized but not found in DB?
                        logger.error("Paper object was initialized but not found in DB after Dify upload success.");
                        // Proceeding with new paper object, but this needs investigation
                        paper = new Paper();
                        paper.setFileName(file.getOriginalFilename());
                        paper.setFileSize(file.getSize());
                        paper.setUploadTime(LocalDateTime.now());
                        paper.setUser(currentUser);
                        paper.setDifyFileId(difyFileId); // Save Dify file ID
                        paper.setStatus("待检测"); // Set initial status to "Pending Detection"
                        paper = paperRepository.save(paper);
                        logger.info("Created new Paper record with ID {} after potential logic flaw.", paper.getId());
                    }
                } else {
                    // Paper object was initialized but doesn't have an ID, likely not saved to DB yet
                    paper = new Paper();
                    paper.setFileName(file.getOriginalFilename());
                    paper.setFileSize(file.getSize());
                    paper.setUploadTime(LocalDateTime.now());
                    paper.setUser(currentUser);
                    paper.setDifyFileId(difyFileId); // Save Dify file ID
                    paper.setStatus("待检测"); // Set initial status to "Pending Detection"
                    paper = paperRepository.save(paper);
                    logger.info("Saved new Paper record with ID {} after potential logic flaw (no ID).", paper.getId());
                }
            }


            // Call Dify Workflow run API with JSON body referencing the file ID
// 在成功获取到 difyFileId 后的代码块中：
            if (difyFileId != null && !difyFileId.isEmpty()) {
                String workflowUrl = difyApiUrl + "/workflows/run";
                logger.info("Calling Dify Workflow run API: {}", workflowUrl);

                HttpHeaders workflowHeaders = new HttpHeaders();
                workflowHeaders.setBearerAuth(difyApiKey);
                workflowHeaders.setContentType(MediaType.APPLICATION_JSON); // Set Content-Type to application/json

                // 构造文件对象
                Map<String, Object> fileObject = new HashMap<>();
                fileObject.put("type", "document");  // 因为是文本文件，使用document类型
                fileObject.put("transfer_method", "local_file");
                fileObject.put("upload_file_id", difyFileId);

                Map<String, Object> inputs = new HashMap<>();
                inputs.put(difyWorkflowFileVariableName, fileObject);  // 使用文件对象而不是直接使用文件ID

                Map<String, Object> workflowBodyMap = new HashMap<>();
                workflowBodyMap.put("workflow_id", difyWorkflowId);
                workflowBodyMap.put("inputs", inputs);
                workflowBodyMap.put("user", "1");
                workflowBodyMap.put("response_mode", "blocking");
                // Convert the map to JSON string
                String workflowJsonBody = objectMapper.writeValueAsString(workflowBodyMap);
                logger.info("Workflow run request body: {}", workflowJsonBody);

                HttpEntity<String> workflowRequestEntity = new HttpEntity<>(workflowJsonBody, workflowHeaders);

                // Using exchange method which is flexible
                ResponseEntity<String> workflowResponse = restTemplate.exchange(
                        workflowUrl,
                        HttpMethod.POST,
                        workflowRequestEntity,
                        String.class
                );


                logger.info("Received workflow response from Dify. Status code: {}", workflowResponse.getStatusCode());
                String workflowResponseBody = workflowResponse.getBody();
                logger.info("Workflow response body: {}", workflowResponseBody);

                try {
                    // 解析 workflow response body, 提取 data -> outputs -> text
                    ObjectMapper objectMapper = new ObjectMapper();
                    JsonNode rootNode = objectMapper.readTree(workflowResponseBody);
                    JsonNode textNode = rootNode.path("data").path("outputs").path("text");
                    
                    if (textNode.isMissingNode() || !textNode.isTextual()) {
                         logger.error("Could not find 'text' in Dify workflow response.");
                         paper.setStatus("处理异常");
                         paper.setAiRawOutput("从Dify响应中提取分析报告失败。");
                    } else {
                        String aiRawOutput = textNode.asText();
                        logger.info("Extracted AI raw output from Workflow run response.");
                        paper.setAiRawOutput(aiRawOutput);
                        paper.setStatus("已检测");
                    }
                    paper.setDetectionTime(LocalDateTime.now());
                    paperRepository.save(paper);
                    logger.info("Paper with ID {} status updated and AI output saved.", paper.getId());

                } catch (JsonProcessingException e) {
                    logger.error("Error parsing Dify workflow response", e);
                    paper.setStatus("处理异常");
                    paper.setAiRawOutput("解析Dify响应JSON时出错。");
                    paperRepository.save(paper);
                }

                JsonNode workflowRunIdNode = new ObjectMapper().readTree(workflowResponseBody).path("workflow_run_id");
                if (!workflowRunIdNode.isMissingNode()) {
                    String workflowRunId = workflowRunIdNode.asText();
                    logger.info("Workflow Run ID: {}", workflowRunId);
                }

                // 返回包含文件信息的 Paper 对象
                return ResponseEntity.ok(paper);

            } else {
                // Should not happen if upload was successful and returned ID
                String errorMessage = "文件上传到 Dify 成功，但未获取到文件 ID，无法执行 Workflow。";
                logger.error(errorMessage);
                if (paper != null && paper.getId() != null) {
                    Optional<Paper> paperToUpdateOpt = paperRepository.findById(paper.getId());
                    if(paperToUpdateOpt.isPresent()){
                        Paper paperToUpdate = paperToUpdateOpt.get();
                        paperToUpdate.setStatus("Dify 文件ID缺失");
                        paperToUpdate.setAiRawOutput(errorMessage);
                        paperRepository.save(paperToUpdate);
                        logger.warn("Paper with ID {} status updated to 'Dify 文件ID缺失'.", paper.getId());
                    } else {
                        logger.warn("Cannot find Paper record with ID {} to update status after missing Dify file ID.", paper.getId());
                    }
                } else {
                    logger.warn("Paper object or ID is null when attempting to update status after missing Dify file ID.");
                }
                return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
            }


        } catch (HttpClientErrorException e) {
            String errorMessage = "与 Dify API 通信时发生 HTTP 客户端错误: " + e.getStatusCode() + " - " + e.getResponseBodyAsString();
            logger.error(errorMessage, e);
            // Attempt to find the latest Paper record for the current user and file to update status
            // This part should ideally happen before the try-catch if paper initialization could fail outside of API calls
            // Given current structure, if \'paper\' is null here, it means Dify upload failed before paper object was created/saved.\
            // If paper is not null but has no ID, it was initialized but not saved before the exception.
            if (paper != null && paper.getId() != null) { // Check if paper was successfully saved to DB before error
                Optional<Paper> paperToUpdateOpt = paperRepository.findById(paper.getId());
                if(paperToUpdateOpt.isPresent()){
                    Paper paperToUpdate = paperToUpdateOpt.get();
                    paperToUpdate.setStatus("Dify API 错误");
                    paperToUpdate.setAiRawOutput(e.getResponseBodyAsString() != null ? e.getResponseBodyAsString() : e.getMessage());
                    paperRepository.save(paperToUpdate);
                    logger.warn("Updated Paper record with ID {} status to 'Dify API 错误' due to HTTP error.", paper.getId());
                } else {
                    logger.warn("Cannot find Paper record with ID {} to update status after Dify API HTTP error.", paper.getId());
                }

            } else {
                // If paper wasn\'t saved, try to find the latest record for the user and file name
                // This is a fallback in case paper object wasn\'t saved before the exception
                String originalFilename = file.getOriginalFilename();
                if (currentUser != null && originalFilename != null) {
                    Optional<Paper> latestPaperOptional = paperRepository.findTopByUserAndFileNameOrderByUploadTimeDesc(currentUser, originalFilename);
                    if(latestPaperOptional.isPresent()){
                        Paper paperToUpdate = latestPaperOptional.get();
                        paperToUpdate.setStatus("Dify API 错误");
                        paperToUpdate.setAiRawOutput(e.getResponseBodyAsString() != null ? e.getResponseBodyAsString() : e.getMessage());
                        paperRepository.save(paperToUpdate);
                        logger.warn("Attempted to update latest Paper record for user {} and file {} with Dify API error (fallback).", currentUser.getUsername(), originalFilename);
                    } else {
                        logger.warn("Cannot find Paper record to update status after Dify API HTTP error (fallback).");
                    }
                } else {
                    logger.warn("Cannot attempt fallback update after Dify API HTTP error: currentUser or originalFilename is null.");
                }
            }
            // 使用 new ResponseEntity<>(body, status)
            return new ResponseEntity<>(errorMessage, e.getStatusCode());
        } catch (ResourceAccessException e) {
            String errorMessage = "与 Dify API 通信时发生资源访问错误（网络问题或其他）：" + e.getMessage();
            logger.error(errorMessage, e);
            if (paper != null && paper.getId() != null) {
                Optional<Paper> paperToUpdateOpt = paperRepository.findById(paper.getId());
                if(paperToUpdateOpt.isPresent()){
                    Paper paperToUpdate = paperToUpdateOpt.get();
                    paperToUpdate.setStatus("网络或Dify连接错误");
                    paperToUpdate.setAiRawOutput(e.getMessage());
                    paperRepository.save(paperToUpdate);
                    logger.warn("Updated Paper record with ID {} status to '网络或Dify连接错误' due to resource access error.", paper.getId());
                } else {
                    logger.warn("Cannot find Paper record with ID {} to update status after Dify API resource error.", paper.getId());
                }

            } else {
                String originalFilename = file.getOriginalFilename();
                if (currentUser != null && originalFilename != null) {
                    Optional<Paper> latestPaperOptional = paperRepository.findTopByUserAndFileNameOrderByUploadTimeDesc(currentUser, originalFilename);
                    if(latestPaperOptional.isPresent()){
                        Paper paperToUpdate = latestPaperOptional.get();
                        paperToUpdate.setStatus("网络或Dify连接错误");
                        paperToUpdate.setAiRawOutput(e.getMessage());
                        paperRepository.save(paperToUpdate);
                        logger.warn("Attempted to update latest Paper record for user {} and file {} with network/resource access error (fallback).", currentUser.getUsername(), originalFilename);
                    } else {
                        logger.warn("Cannot find Paper record to update status after Dify API resource error (fallback).");
                    }
                } else {
                    logger.warn("Cannot attempt fallback update after Dify API resource error: currentUser or originalFilename is null.");
                }
            }
            // 使用 new ResponseEntity<>(body, status)
            return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        catch (IOException e) {
            String errorMessage = "处理文件上传或Dify API响应时发生 IO 错误: " + e.getMessage();
            logger.error(errorMessage, e);
            if (paper != null && paper.getId() != null) {
                Optional<Paper> paperToUpdateOpt = paperRepository.findById(paper.getId());
                if(paperToUpdateOpt.isPresent()){
                    Paper paperToUpdate = paperToUpdateOpt.get();
                    paperToUpdate.setStatus("服务器内部错误");
                    paperToUpdate.setAiRawOutput(e.getMessage());
                    paperRepository.save(paperToUpdate);
                    logger.warn("Updated Paper record with ID {} status to '服务器内部错误' due to IO error.", paper.getId());
                } else {
                    logger.warn("Cannot find Paper record with ID {} to update status after IO error.", paper.getId());
                }

            } else {
                String originalFilename = file.getOriginalFilename();
                if (currentUser != null && originalFilename != null) {
                    Optional<Paper> latestPaperOptional = paperRepository.findTopByUserAndFileNameOrderByUploadTimeDesc(currentUser, originalFilename);
                    if(latestPaperOptional.isPresent()){
                        Paper paperToUpdate = latestPaperOptional.get();
                        paperToUpdate.setStatus("服务器内部错误");
                        paperToUpdate.setAiRawOutput(e.getMessage() != null ? e.getMessage() : "未知错误");
                        paperRepository.save(paperToUpdate);
                        logger.warn("Attempted to update latest Paper record for user {} and file {} with internal server error (fallback).", currentUser.getUsername(), originalFilename);
                    } else {
                        logger.warn("Cannot find Paper record to update status after IO error (fallback).");
                    }
                } else {
                    logger.warn("Cannot attempt fallback update after IO error: currentUser or originalFilename is null.");
                }
            }
            // 使用 new ResponseEntity<>(body, status)
            return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (Exception e) {
            String errorMessage = "处理文件上传时发生未知错误: " + e.getMessage();
            logger.error(errorMessage, e);
            if (paper != null && paper.getId() != null) {
                Optional<Paper> paperToUpdateOpt = paperRepository.findById(paper.getId());
                if(paperToUpdateOpt.isPresent()){
                    Paper paperToUpdate = paperToUpdateOpt.get();
                    paperToUpdate.setStatus("未知错误");
                    paperToUpdate.setAiRawOutput(e.getMessage() != null ? e.getMessage() : "未知错误");
                    paperRepository.save(paperToUpdate);
                    logger.warn("Updated Paper record with ID {} status to '未知错误' due to unknown error.", paper.getId());
                } else {
                    logger.warn("Cannot find Paper record with ID {} to update status after unknown error.", paper.getId());
                }

            } else {
                String originalFilename = file.getOriginalFilename();
                if (currentUser != null && originalFilename != null) {
                    Optional<Paper> latestPaperOptional = paperRepository.findTopByUserAndFileNameOrderByUploadTimeDesc(currentUser, originalFilename);
                    if(latestPaperOptional.isPresent()){
                        Paper paperToUpdate = latestPaperOptional.get();
                        paperToUpdate.setStatus("未知错误");
                        paperToUpdate.setAiRawOutput(e.getMessage() != null ? e.getMessage() : "未知错误");
                        paperRepository.save(paperToUpdate);
                        logger.warn("Attempted to update latest Paper record for user {} and file {} with unknown error (fallback).", currentUser.getUsername(), originalFilename);
                    } else {
                        logger.warn("Cannot find Paper record to update status after unknown error (fallback).");
                    }
                } else {
                    logger.warn("Cannot attempt fallback update after unknown error: currentUser or originalFilename is null.");
                }
            }
            // 使用 new ResponseEntity<>(body, status)
            return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    // Existing methods for listPapers, getPaperDetails, deletePaper, etc. should follow here
    @PostMapping(value = "/{paperId}/process-result", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> processResult(@PathVariable Long paperId, @RequestBody Map<String, String> result) {
        try {
            Optional<Paper> paperOptional = paperRepository.findById(paperId);
            if (!paperOptional.isPresent()) {
                return new ResponseEntity<>("论文不存在", HttpStatus.NOT_FOUND);
            }

            Paper paper = paperOptional.get();
            paper.setStatus("已检测");
            paper.setAiRawOutput(result.get("result"));
            paper.setDetectionTime(LocalDateTime.now());
            paperRepository.save(paper);

            return new ResponseEntity<>(paper, HttpStatus.OK);
        } catch (Exception e) {
            logger.error("Error while processing result: ", e);
            return new ResponseEntity<>("处理检测结果失败：" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @GetMapping("/list")
    public ResponseEntity<List<Paper>> listPapers(Principal principal) {
        String username = principal.getName();
        // 正确处理 Optional<User>
        Optional<User> userOptional = userRepository.findByUsername(username);
        if (userOptional.isEmpty()) {
            // 对于已认证的用户，这理论上不应该发生
            // 返回一个空列表是安全的做法
            return ResponseEntity.ok(Collections.emptyList());
        }
        User user = userOptional.get();
        // 调用新的排序方法
        List<Paper> papers = paperRepository.findByUserOrderByUploadTimeDesc(user);
        return ResponseEntity.ok(papers);
    }

    @GetMapping("/{paperId}")
    public ResponseEntity<Paper> getPaperById(@PathVariable Long paperId, Principal principal) {
        // 通过 paperId 查找论文，并直接判断所有权
        return paperRepository.findById(paperId)
                .map(paper -> {
                    // 检查论文所有者是否是当前登录用户
                    if (!paper.getUser().getUsername().equals(principal.getName())) {
                        // 如果不是，返回 403 Forbidden
                        return new ResponseEntity<Paper>(HttpStatus.FORBIDDEN);
                    }
                    // 如果是，返回论文详情
                    return ResponseEntity.ok(paper);
                })
                // 如果找不到论文，返回 404 Not Found
                .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @DeleteMapping("/{paperId}")
    public ResponseEntity<?> deletePaper(@PathVariable Long paperId, Principal principal) {
        if (principal == null) {
            logger.warn("Cannot delete paper for unauthenticated user.");
            return new ResponseEntity<>("用户未认证，无法删除论文。", HttpStatus.UNAUTHORIZED);
        }

        // 直接通过 principal.getName() 获取用户名，这是最简单和可靠的方式
        String username = principal.getName();

        // 查找要删除的论文
        Optional<Paper> paperOptional = paperRepository.findById(paperId);

        if (paperOptional.isPresent()) {
            Paper paper = paperOptional.get();
            // 检查请求删除的用户是否是论文的所有者
            if (!paper.getUser().getUsername().equals(username)) {
                logger.warn("User {} attempted to delete paper {} belonging to user {}", username, paperId, paper.getUser().getUsername());
                return new ResponseEntity<>("无权删除此论文。", HttpStatus.FORBIDDEN);
            }

            try {
                // 删除数据库记录
                paperRepository.delete(paper);
                logger.info("Deleted paper record with ID {} for user {}", paperId, username);

                return new ResponseEntity<>("论文删除成功。", HttpStatus.OK);
            } catch (Exception e) {
                logger.error("删除论文时发生错误: {}", e.getMessage(), e);
                return new ResponseEntity<>("删除论文时发生服务器内部错误。", HttpStatus.INTERNAL_SERVER_ERROR);
            }

        } else {
            logger.warn("Paper with ID {} not found for deletion.", paperId);
            return new ResponseEntity<>("未找到指定论文。", HttpStatus.NOT_FOUND);
        }
    }
    //这个是6.9更新后的文件，已经可以正常上传
}